package com.gitee.sparta.core.bean.cluster;

import java.util.HashSet;
import java.util.Set;

/**
 * <p>
 *      指令集
 * </p>
 *
 * @author zyred
 * @since v 1.0.0
 */
public class ClusterCmd {

    /** 切换 leader **/
    public final static byte SWITCHOVER_LEADER = -4;

    /** 询问是否是 leader **/
    public final static byte ASK_LEADER = -3;

    /** 服务属性是 follower, 关闭 leader 线程 **/
    public final static byte STOP_LEADER_SENDER = -2;

    /** follower 晋升成为 leader 后，需要停止 send worker 线程 **/
    public final static byte WORKER_SEND_STOP = -1;

    /** 心跳 leader 使用 **/
    public final static byte HEARTBEAT = 0;

    /** 下一轮选举，依然是 follower **/
    public final static byte NEXT_FOLLOWER = 1;

    /** 连接上服务器: leader <- follower **/
    public final static byte CHANNEL_ACCEPT = 2;

    /** follower 连接上 leader 后的响应 **/
    public final static byte ACCEPT_RESPONSE = 3;

    /** 客户端收添加到队列的消息，需要通知 leader carry 线程 **/
    public final static byte INTERCEPTOR = 4;

    /** follower 错误，无法消费消息 **/
    public final static byte FOLLOWER_ERROR = 5;

    /** follower 恢复，可以进行消费 **/
    public final static byte FOLLOWER_RECOVER = 6;

    /** 启动消费队列数据：leader -> follower **/
    public final static byte CONSUME_QUEUE_DATA = 7;

    /** 启动消费广播数据：leader -> follower **/
    public final static byte CONSUME_BROADCAST_DATA = 8;

    /** 从节点宕机：当然 leader 不一定能收到这条消息 **/
    public final static byte FOLLOWER_SHUTDOWN = 9;

    /** 当 leader 检测到 follower read timeout 的时候，发送一次 ping 到 follower **/
    public final static byte PING = 111;

    /** follower 收到 ping 后返回 pong，证明自己没有死掉 **/
    public final static byte PONG = 112;


    // ----------------------- Leader 内部通讯 ----------------------------

    private static final Set<Byte> LEADER_INNER_CMD = new HashSet<>();

    /** 刷新 server table 指令 **/
    public final static byte FLUSH_SERVER_TABLE = 10;
    /** 从 loadBalance 中移除 **/
    public final static byte REMOVE_LOAD_BALANCE = 11;



    static {
        LEADER_INNER_CMD.add(REMOVE_LOAD_BALANCE);
        LEADER_INNER_CMD.add(FLUSH_SERVER_TABLE);
        LEADER_INNER_CMD.add(STOP_LEADER_SENDER);
    }

    public static boolean isLeaderInnerCmd (byte cmd) {
        return LEADER_INNER_CMD.contains(cmd);
    }
}
